import { Inject, Provide } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { NovelEntity } from 'src/entity/novel/novel';
import { NovelPartEntity } from 'src/entity/part/part';
import {  Brackets, Repository ,  } from "typeorm";
// import { Brackets, Repository  } from "typeorm";
import { Context } from '@midwayjs/koa';
// import * as jwt from 'jsonwebtoken';
import { novellistDTO, novelnumDTO } from 'src/dto/novel';
// import { novelnumDTO } from 'src/dto/novel';
import { RedisService } from '@midwayjs/redis';
import { PayService } from './onlypay.service';
import { pageOptions } from 'src/interface';
import { StatisticEntity } from 'src/entity/Statistics/Statistics';
import { AdvertisementEntity } from 'src/entity/admin/advertisement';


@Provide()
export class NovelService {

    @Inject()
    ctx: Context

    @InjectEntityModel(NovelEntity)
    NovelModel: Repository<NovelEntity>;
    @InjectEntityModel(NovelPartEntity)
    NovelPartModel: Repository<NovelPartEntity>;
    @InjectEntityModel(StatisticEntity)
    StatisticModel: Repository<StatisticEntity>;
    @InjectEntityModel(AdvertisementEntity)
    AdvertisementModel: Repository<AdvertisementEntity>;

    @Inject()
    redisService: RedisService;
    @Inject()
    PayService: PayService;

  //
  async getNovel(options:any ) {
    console.log('菜单id12323123',options);
    
    let Novel = await this.NovelModel.createQueryBuilder('novel')
    // .where("novel.id = :id  ", {  id: options.id })
    .andWhere('novel.approveStatus =1')
    .leftJoinAndSelect('novel.novels','item')
    .select(['novel'])
    .addSelect(['item.articleTitle',"item.sort",'item.status'])  // cwt修改：发送数据携带status
    .orderBy({"item.sort":"ASC"})
    .cache(true)
    .getOne()
    return { 
      code:2000,
      msg:"success",
      data:Novel
    }
  }
  async novellistNumone(options:any ) {
    console.log('菜单id',options);
    
    let Novel = await this.NovelModel.createQueryBuilder('novel')
    .where("novel.id = :id", {  id: options.id })
    .cache(true)
    .getOne()
    return { 
      code:2000,
      msg:"success",
      data:Novel
    }
  }


  async getextension(){
      // 
         return { 
              code:20000,
              data:await this.AdvertisementModel.find()
         }
  } 

  //  测试 redis setredis
  async setredis(options:any ) {
    console.log('菜单id',options);
    //  第一次参数 是键名  唯一的 , 存 相同的key   后者覆盖前者
    var  key  = "testredis:"+options.id
    var  value = options.sort
        let result   =await  this.redisService.set(key ,value ,'EX',30 )
   
    return { 
      result,key,value
    }
  }
  async getredis(options:any ) {
    console.log('菜单id',options);
    //  第一次参数 是键名  唯一的 , 存 相同的key   后者覆盖前者
    var  key  = "testredis:"+options.id
    // var  value = options.sort
        let result   = await  this.redisService.get(key)
        // 自增
        // let result   = await       this.redisService.incr(key)
    return { 
      result
    }
  }









  // 获得小说章节
  async getNovelitem(options:novelnumDTO ) {
    console.log("options" , options);
    
    let Novel = await this.NovelPartModel.createQueryBuilder('novel')
    .where("novel.sort = :sort ", { sort:options.sort})
    .andWhere(' novel.pidId = :id ' ,{ id :options.id }  )
    .cache(true)
    .getOne()

    console.log(Novel?.status);
    //  判断是否有登录
    console.log('this.ctx.get("authorization")',this.ctx.get("authorization"));
    
    if(this.ctx.get("authorization")){
      try{ 
        console.log("准备存库");
        
      var    user   =  await this.PayService.getuserinfo()
      console.log("存库存");

        let get1      =  await this.redisService.get('userhistory:'+user.id+"");
        console.log("redis获取",get1);
        
        if(get1 == null){
           console.log('get1null',get1);
           get1 = '{}' 
        }
          get1  =  JSON.parse(get1)
        
       get1[''+options.id ] = options.sort 
       let result=  await this.redisService.set('userhistory:'+user.id+"", JSON.stringify(get1) );
        console.log(result);
      }catch (err){ 
          console.log(err);
          
      }
      //  获取是谁 添加到历史
 
      
    }
   
    var userStatus = true
    if(Novel?.status  ){
      //  用户购买力了就不需要 截取
            // 查下用户是否购买 , 需要获取token 查找id 查找订单
            // this.OrderModel.find(  {     } )
            userStatus = false
        if(this.ctx.get("authorization")){
          var  book =await    this.redisService.get('userbook:'+user.id+"");
      
          var arr 
            if(book ==null){
             arr =[]
            }else{
              arr = book.split(",")
            }
       
         
            console.log( "是否已经够",   arr.includes( options.id+""));
            console.log( "用户id",user.id );
            if(arr.includes( options.id+"")){
              //  说明已经购买
              userStatus = true
            }else{
              Novel.articleContent =  Novel.articleContent.substring(0,200)
            }
          }else{
            Novel.articleContent =  Novel.articleContent.substring(0,200)
          }

         
            // 如果用户购买了  再添加一个属性给你 
    }

    //  添加浏览记录
    //  自增
    this.redisService.hincrby('novel:view',options.id+"" , 1)
    this.redisService.hincrby('novel:sort',options.id+"/"+options.sort , 1)

    if(Novel ==null){
        return { 
          message:"无此章节"
        }
          
    }
    

    return { 
        ...Novel,
        userStatus
    }
  }



  
  // 添加小说 , 传小说
  async addtNovel(options:NovelEntity ) {
    let  result   = await this.NovelModel.createQueryBuilder('novel') .insert()
    .into(NovelEntity)
    .values( options)
    .execute();
    return { 
        code:20000,
        message:"添加成功",
        data: result
    }
  }

    // 添加章节 , 传小说
    async addtNovelitemNode(options:NovelPartEntity  ) {
      
      await this.NovelPartModel.createQueryBuilder('novel') .insert()
      .into(NovelPartEntity)
      .values( options)
      .execute();
      return { 
        code:20000,
        message:"添加成功",
        data: options.sort
      }
    }
  

  // 获得用户信息
  // async getuserinfo(){
  //   let result = await  jwt.verify(this.ctx.get("Authorization"),'asdasd')
  //   console.log("解析", typeof result == 'object');
  //   if( typeof result == 'object'){
  //     return result
  //   }
  // }


  async novellist(option:novellistDTO , selectoption={  keyWordLikeFields :['name','author']   }){
    let { order ={ 'CreateDate': 'DESC'},  page=1 , size=6 ,keyWord=""  ,where={     }   } = option;
    // let { order ={ 'createTime': 'DESC'}, page=10 , size=15,keyWord=""  ,where={ }  } = option;

    
    //  创建一个查询器
    let find   =   this.NovelModel.createQueryBuilder('novel')
//   //属性范围查询 单个 就精准    数组即范围 key 查询目标
  for(   let key     in  where){
    if(!Array.isArray(where[key])){
        //  精准查询
        console.log(`novel.${key}  = :a`, where[key]);
        //  为了防止 多个 where  不被覆盖 统一 andwhere
        find.andWhere(`novel.${key}  = :a`, { a : where[key] })
    }else{ 
    //  为数组 求范围
        console.log("求范围",`novel.${key}  <= :a`, where[key][1] );
        
          find.andWhere(`novel.${key}  >= :a`, { a :  where[key][0]})
         
        where[key][1]> where[key][0]   &&    find.andWhere(`novel.${key}  <= :b`, { b :  where[key][1]})

    }
}





// //关键词模糊搜索
    if(keyWord || keyWord == 0 ){
      keyWord =  `%${keyWord}%`
      
        find.andWhere(new Brackets( qb =>{ 

          
          selectoption.keyWordLikeFields.forEach( (v,i) =>{
            // console.log(v);
            
            qb.orWhere(`novel.${v} like :name`, { name :  keyWord}) 
             // i == 0 ?   find.orWhere(`novel.${v} like :name`, { name :  keyWord}) : find.orWhere(`novel.${v} like :name`, { name :  keyWord})
         })
        }) )


        find.where(`novel.approveStatus = 1` )
     
    
     
  
    }

  




//   // //  处理oder
    var orderobj = { }
     for( let key in order  ){
      orderobj[`novel.${key}`]  =order[key]
     }     


     find.orderBy(orderobj)


   let a =  await find
        .skip((page-1)*size)
        .take(size)
        .getManyAndCount()
      
      
        

    return  { 
          code:20000,
          message:"success",
          data:{
             list: a[0],
             pagination:{
                page:option.page,
                size:option.size,
                total:a[1]
             }
          }
    }

  }






  async pagelist(option:novellistDTO , selectoption={ keyWordLikeFields :['name','author']   }  ,  entity:Repository<object> ){
    let { order ={ 'CreateDate': 'DESC'},  page=10 , size=15 ,keyWord=""  ,where={     }   } = option;

    //  创建一个查询器
    let find   =   entity.createQueryBuilder('novel')
  for(   let key     in  where){
    if(!Array.isArray(where[key])){
        //  精准查询
        console.log(`novel.${key}  = :a`, where[key]);
        //  为了防止 多个 where  不被覆盖 统一 andwhere
        find.andWhere(`novel.${key}  = :a`, { a : where[key] })
    }else{ 
    //  为数组 求范围
        console.log("求范围",`novel.${key}  <= :a`, where[key][1] );
        
          find.andWhere(`novel.${key}  >= :a`, { a :  where[key][0]})
         
        where[key][1]> where[key][0]   &&    find.andWhere(`novel.${key}  <= :b`, { b :  where[key][1]})

    }
}





// //关键词模糊搜索
    if(keyWord || keyWord == 0 ){
      keyWord =  `%${keyWord}%`
      
        find.andWhere(new Brackets( qb =>{ 
          selectoption.keyWordLikeFields.forEach( (v,i) =>{
            // console.log(v);
              console.log(selectoption);
              
            qb.orWhere(`novel.${v} like :name`, { name :  keyWord}) 
             // i == 0 ?   find.orWhere(`novel.${v} like :name`, { name :  keyWord}) : find.orWhere(`novel.${v} like :name`, { name :  keyWord})
         })
        }) )
    }

  




//   // //  处理oder
    var orderobj = { }
     for( let key in order  ){
      orderobj[`novel.${key}`]  =order[key]
     }     
     find.orderBy(orderobj)


   let a =  await find
        .skip((page-1)*size)
        .take(option.size)
        .getManyAndCount()
      
      
        

    return  { 
          code:20000,
          message:"success",
          data:{
             list: a[0],
             pagination:{
                page:option.page,
                size:option.size,
                total:a[1]
             }
          }
    }

  }




  
  async adminPagelist2(option:novellistDTO , 
    selectoption :pageOptions={ keyWordLikeFields :[] , leftJonin:[] ,count:[]
   }  ,  entity:Repository<object> ){

    // var  option1 :{ 
    //     page:1,
    //     size:15
    // }

    // var  option2 = Object.assign(option1 ,option )

    // console.log("融合对象", option2);
    
    let { order ={ 'CreateDate': 'DESC'},  page=10 , size=15 ,keyWord=""  ,where={     }  , AndWhere  } = option;
      console.log(AndWhere);
      





    //  创建一个查询器
    let find   =   entity.createQueryBuilder('a')

    // find.select('*')
    // find.select('a')

    // 联查子表 , 数据太大 取消
    if(selectoption?.leftJonin?.length){
      console.log( "连表查询11111111",selectoption?.leftJonin);
        if( Array.isArray(selectoption.leftJonin[0] )){
          // 如果也为数组 说明要连表多个
          selectoption.leftJonin.forEach( v =>{
            find.leftJoinAndSelect.apply( find, v  )
          })
        }else{
          find.leftJoinAndSelect.apply( find,  selectoption.leftJonin  )
        }
     
    }
    if(selectoption?.count?.length){
    //  计算总数
    // find.loadRelationCountAndMap('novel.partSum', 'novel.novels')
      find.loadRelationCountAndMap.apply( find,  selectoption.count )
    }

    
    for(   let key     in  where){
    if(!Array.isArray(where[key])){
        //  精准查询
        console.log(`a.${key}  = :a`, where[key]);
        //  为了防止 多个 where  不被覆盖 统一 andwhere
        find.andWhere(`a.${key}  = :a`, { a : where[key] })
    }else{ 
    //  为数组 求范围
        console.log("求范围",`a.${key}  <= :a`, where[key][1] );
        
          find.andWhere(`a.${key}  >= :a`, { a :  where[key][0]})
        
        where[key][1]> where[key][0]   &&    find.andWhere(`a.${key}  <= :b`, { b :  where[key][1]})

    }
}



    for(  let  key  in  AndWhere ){
      find.andWhere( new Brackets( qb=>{
        if( !Array.isArray(AndWhere[key]) ){
          AndWhere[key] =  [ AndWhere[key] ]
        }
        AndWhere[key].forEach( (v:any)=>{
          if(key.includes('.')){
            console.log("连表条件查询进行中");
            
            // qb.orWhere( `novel.name =  '1'`   )  静态测试成功
            qb.orWhere( ` ${key}=  '${v}'`   ) 


          }else{
            qb.orWhere( `a.${key} = '${v}'`   )
          }
       
          // qb.orWhere( `novel.${key} =  ${v}`   )
        } )
      

                  
      
      } )  )
    }

  




// //关键词模糊搜索
    if(keyWord || keyWord == 0 ){
      keyWord =  `%${keyWord}%`
      
        find.andWhere(new Brackets( qb =>{ 
          selectoption.keyWordLikeFields.forEach( (v,i) =>{
            // console.log(v);
              console.log(selectoption);
              
            qb.orWhere(`a.${v} like :name`, { name :  keyWord}) 
             // i == 0 ?   find.orWhere(`novel.${v} like :name`, { name :  keyWord}) : find.orWhere(`novel.${v} like :name`, { name :  keyWord})
         })
        }) )


     
    
     
  
    }

  




//   // //  处理oder
    var orderobj = { }
     for( let key in order  ){
      orderobj[`a.${key}`]  =order[key]
     }     
     find.orderBy(orderobj)




     
   var a =  await find
        .skip((page-1)*size)
        .take(size)
        .getManyAndCount ()
      
      
        
     console.log(a);





// console.log(b); 


//  查询总数 
let find2   =   entity.createQueryBuilder('a')


      
find2
.select([])
.addSelect("SUM(if(  orderStatus =1 ,actualPrice, 0))", "totalAmount")
.addSelect("SUM(if(settlementStatus = '0'  and orderStatus =1 ,actualPrice, 0))", "toBeSettled")

 // //关键词模糊搜索
if(keyWord || keyWord == 0 ){
 keyWord =  `%${keyWord}%`

   find2.andWhere(new Brackets( qb =>{ 
     selectoption.keyWordLikeFields.forEach( (v,i) =>{
       // console.log(v);
         console.log(selectoption);
       
       qb.orWhere(`a.${v} like :name`, { name :  keyWord}) 
        // i == 0 ?   find2.orWhere(`novel.${v} like :name`, { name :  keyWord}) : find2.orWhere(`novel.${v} like :name`, { name :  keyWord})
    })
   }) )
}

for(   let key     in  where){
if(!Array.isArray(where[key])){
   //  精准查询
   console.log(`a.${key}  = :a`, where[key]);
   //  为了防止 多个 where  不被覆盖 统一 andwhere
   find2.andWhere(`a.${key}  = :a`, { a : where[key] })
}else{ 
//  为数组 求范围
   console.log("求范围",`a.${key}  <= :a`, where[key][1] );
   
     find2.andWhere(`a.${key}  >= :a`, { a :  where[key][0]})
   
   where[key][1]> where[key][0]   &&    find2.andWhere(`a.${key}  <= :b`, { b :  where[key][1]})

}
}

 
let b =await find2.getRawMany();




     
    return  { 
          code:20000,
          message:"success",
          data:{
             list: a[0],
             sum : b,
             pagination:{
                page:page,
                size:size,
                total:a[1]
             }
          }
    }

  }
  
  async adminPagelist(option:novellistDTO , 
    selectoption :pageOptions={ keyWordLikeFields :[] , leftJonin:[] ,count:[]
   }  ,  entity:Repository<object> ){

    // var  option1 :{ 
    //     page:1,
    //     size:15
    // }

    // var  option2 = Object.assign(option1 ,option )

    // console.log("融合对象", option2);
    
    let { order ={ 'CreateDate': 'DESC'},  page=10 , size=15 ,keyWord=""  ,where={     }  , AndWhere  } = option;
      console.log(AndWhere);
      





    //  创建一个查询器
    let find   =   entity.createQueryBuilder('a')

    // find.select('*')
    // find.select('a')

    // 联查子表 , 数据太大 取消
    if(selectoption?.leftJonin?.length){
      console.log( "连表查询11111111",selectoption?.leftJonin);
        if( Array.isArray(selectoption.leftJonin[0] )){
          // 如果也为数组 说明要连表多个
          selectoption.leftJonin.forEach( v =>{
            find.leftJoinAndSelect.apply( find, v  )
          })
        }else{
          find.leftJoinAndSelect.apply( find,  selectoption.leftJonin  )
        }
     
    }
    if(selectoption?.count?.length){
    //  计算总数
    // find.loadRelationCountAndMap('novel.partSum', 'novel.novels')
      find.loadRelationCountAndMap.apply( find,  selectoption.count )
    }

    
    for(   let key     in  where){
    if(!Array.isArray(where[key])){
        //  精准查询
        console.log(`a.${key}  = :a`, where[key]);
        //  为了防止 多个 where  不被覆盖 统一 andwhere
        find.andWhere(`a.${key}  = :a`, { a : where[key] })
    }else{ 
    //  为数组 求范围
        console.log("求范围",`a.${key}  <= :a`, where[key][1] );
        
          find.andWhere(`a.${key}  >= :a`, { a :  where[key][0]})
        
        where[key][1]> where[key][0]   &&    find.andWhere(`a.${key}  <= :b`, { b :  where[key][1]})

    }
}



    for(  let  key  in  AndWhere ){
      find.andWhere( new Brackets( qb=>{

        AndWhere[key].forEach( (v:any)=>{
          if(key.includes('.')){
            console.log("连表条件查询进行中");
            
            // qb.orWhere( `novel.name =  '1'`   )  静态测试成功
            qb.orWhere( ` ${key}=  '${v}'`   ) 


          }else{
            qb.orWhere( `a.${key} = '${v}'`   )
          }
       
          // qb.orWhere( `novel.${key} =  ${v}`   )
        } )
      

                  
      
      } )  )
    }

  




// //关键词模糊搜索
    if(keyWord || keyWord == 0 ){
      keyWord =  `%${keyWord}%`
      
        find.andWhere(new Brackets( qb =>{ 
          selectoption.keyWordLikeFields.forEach( (v,i) =>{
            // console.log(v);
              console.log(selectoption);
              
            qb.orWhere(`a.${v} like :name`, { name :  keyWord}) 
             // i == 0 ?   find.orWhere(`novel.${v} like :name`, { name :  keyWord}) : find.orWhere(`novel.${v} like :name`, { name :  keyWord})
         })
        }) )


     
    
     
  
    }

  




//   // //  处理oder
    var orderobj = { }
     for( let key in order  ){
      orderobj[`a.${key}`]  =order[key]
     }     
     find.orderBy(orderobj)




     
   var a =  await find
        .skip((page-1)*size)
        .take(size)
        .getManyAndCount ()
      
      
        
     console.log(a);





// console.log(b); 





     
    return  { 
          code:20000,
          message:"success",
          data:{
             list: a[0],
      
             pagination:{
                page:page,
                size:size,
                total:a[1]
             }
          }
    }

  }




  async deltenovel(id:number){
       let result =     await  this.NovelPartModel.createQueryBuilder().delete().where("Pid = :id", { id }).execute();
        let result2 =  await  this.NovelModel.createQueryBuilder().delete().where("id = :id", { id }).execute();
        return {
           code:20000,
           data:{
              novel : result2,
              part:result
           }
        }
  }

  async approveStatus(body:any){
          
         return { 
            code:20000,
            data: await  this.NovelModel.createQueryBuilder().update().set({ approveStatus: body.approveStatus  }).where('id =:id',{ id:  body.id }) .execute()
         }
  }
  async ishot(body:any){

         return { 
            code:20000,
            data: await  this.NovelModel.createQueryBuilder().update().set({ isHot: body.isHot  }).where('id =:id',{ id:  body.id }) .execute()
         }
  }
  async evaluateNum(body:any){

         return { 
            code:20000,
            data: await  this.NovelModel.createQueryBuilder().update().set({ evaluateNum: body.evaluateNum  }).where('id =:id',{ id:  body.id }) .execute()
         }
  }

}